package qinggui.mlz.module.utils;


import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.poi.ss.usermodel.Cell;

import java.math.BigInteger;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;

public class BaseUtils {
    /**
     * 获取秒级时间戳
     *
     * @return 秒级时间戳
     */
    public static int currentSeconds() {
        return (int) (System.currentTimeMillis() / 1000);
    }

    /**
     * 判断参数是否为空
     *
     * @param obj 校验的对象
     * @return true表示为空，false表示不为空
     */
    public static boolean isEmpty(Object obj) {
        if (obj instanceof List) {
            return obj == null || ((List<?>) obj).isEmpty();
        } else if (obj instanceof Number) {
            DecimalFormat decimalFormat = new DecimalFormat();
            try {
                return decimalFormat.parse(obj.toString()).doubleValue() == 0;
            } catch (ParseException e) {
                e.printStackTrace();
                return false;
            }
        } else {
            return obj == null || "".equals(obj.toString());
        }
    }

    /**
     * md5加密
     *
     * @param text 待加密字符串
     * @return 32位加密字符串
     */
    public static String md5(String text) {
        String encodeStr = "";
        try {
            encodeStr = DigestUtils.md5Hex(text);
        } catch (Exception e) {
            return encodeStr;
        }
        return encodeStr;
    }

    /**
     * 时间戳转换成日期格式字符串
     *
     * @param seconds 精确到秒的字符串
     * @return 时间戳对应的日期字符串
     */
    public static String timeStamp2Date(int seconds) {
        return timeStamp2Date(seconds, null);
    }

    /**
     * 时间戳转换成日期格式字符串
     *
     * @param seconds 时间戳（秒）
     * @param format  日期格式字符串，如果为空则使用默认格式"yyyy-MM-dd HH:mm:ss"
     * @return 时间戳对应的日期字符串
     */
    public static String timeStamp2Date(int seconds, String format) {
        if (isEmpty(seconds)) {
            return "";
        }
        if (format == null || format.isEmpty()) {
            format = "yyyy-MM-dd HH:mm:ss";
        }
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(new Date(Long.valueOf(seconds + "000")));
    }

    /**
     * 将时间戳转换为GMT格式的日期字符串
     *
     * @param seconds 时间戳（秒）
     * @param format  日期格式字符串，如果为空则使用默认格式"yyyy-MM-dd HH:mm:ss"
     * @return 格式化后的日期字符串，如果时间戳为空则返回空字符串
     */
    public static String timeStamp2DateGMT(int seconds, String format) {
        if (isEmpty(seconds)) {
            return "";
        }
        if (format == null || format.isEmpty()) {
            format = "yyyy-MM-dd HH:mm:ss";
        }
        SimpleDateFormat sdf = new SimpleDateFormat(format, Locale.US);
        return sdf.format(new Date(Long.valueOf(seconds + "000")));
    }

    /**
     * 日期格式字符串转换成时间戳
     *
     * @param date_str 字符串日期
     * @return 时间戳
     */
    public static int date2TimeStamp(String date_str) {
        return date2TimeStamp(date_str, null);
    }

    /**
     * 将日期字符串转换为秒级时间戳
     *
     * @param date_str 日期字符串，格式应与format参数匹配
     * @param format   日期格式字符串，如果为空则默认使用"yyyy-MM-dd HH:mm:ss"
     * @return 转换后的时间戳（秒级），转换失败时返回0
     */
    public static int date2TimeStamp(String date_str, String format) {
        // 检查输入参数是否为空
        if (date_str == null || date_str.isEmpty()) {
            return 0;
        }
        // 如果format为空，则使用默认格式
        if (format == null || format.isEmpty()) {
            format = "yyyy-MM-dd HH:mm:ss";
        }
        try {
            // 如果输入的字符串是纯数字，假设它已经是时间戳了
            if (date_str.matches("\\d+")) {
                long timestamp = Long.parseLong(date_str);
                // 如果是10位数字，直接返回；如果是13位毫秒级时间戳，转换为秒
                if (String.valueOf(timestamp).length() == 10) {
                    return (int) timestamp;
                } else if (String.valueOf(timestamp).length() == 13) {
                    return (int) (timestamp / 1000);
                } else {
                    // 其他情况当作秒级时间戳处理
                    return (int) timestamp;
                }
            }
            // 否则按日期格式解析
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            return (int) (sdf.parse(date_str).getTime() / 1000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 获得指定长度的随机数
     *
     * @param num 随机数长度
     * @return 随机数字符串
     */
    public static String getRandNumber(int num) {
        Random random = new Random();
        StringBuffer result = new StringBuffer();
        for (int i = 0; i < num; i++) {
            result.append(random.nextInt(9) + 1);
        }
        return result.toString();
    }

    /**
     * 生成指定长度的随机字符串
     *
     * @param size 指定生成随机字符串的长度
     * @return 返回生成的随机字符串
     */
    public static String getRandString(int size) {
        String abc = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890";
        //指定长度size = 30
        //指定取值范围 abc 如果不指定取值范围，中文环境下会乱码
        String str = RandomStringUtils.random(size, abc);
        return str;
    }

    /**
     * 格式化价格显示
     *
     * @param price 价格数值
     * @return 带有货币符号的格式化价格字符串
     */
    public static String formatPrice(int price) {
        String prefix = "￥";
        return prefix + formatPriceNum(price);
    }

    /**
     * 格式化价格显示
     *
     * @param price 价格参数，使用BigInteger类型传入
     * @return 格式化后的价格字符串
     */
    public static String formatPrice(BigInteger price) {
        int priceInt = price.intValue();
        return formatPrice(priceInt);
    }

    /**
     * 格式化价格数字，将分为单位的价格转换为元为单位的字符串表示
     *
     * @param price 以分为单位的价格整数
     * @return 格式化后的价格字符串，格式为"元.分"，分部分始终显示两位数字
     */
    public static String formatPriceNum(int price) {
        int points = (price % 100);
        if (points == 0) {
            return (price / 100) + ".00";
        } else {
            String pointStr = new DecimalFormat("00").format(points);
            return (price / 100) + "." + pointStr;
        }
    }

    /**
     * 格式化价格数值
     *
     * @param price 价格数值，以BigInteger类型传入
     * @return 格式化后的价格字符串
     */
    public static String formatPriceNum(BigInteger price) {
        int priceInt = price.intValue();
        return formatPriceNum(priceInt);
    }

    /**
     * 格式化重量值为带小数点的字符串显示格式
     *
     * @param weight 重量值，单位为克
     * @return 格式化后的重量字符串，单位转换为千克(Kg)，保留小数点后两位
     */
    public static String formatWeight(int weight) {
        String endFix = "Kg";
        int points = (weight % 1000);
        if (points == 0) {
            return (weight / 1000) + ".00" + endFix;
        } else {
            return (weight / 1000) + "." + points + endFix;
        }
    }

    /**
     * 将两个搜索参数合并为一个字符串
     *
     * @param param1 第一个搜索参数
     * @param param2 第二个搜索参数
     * @return 合并后的字符串，如果两个参数都为空则返回null，如果只有一个参数有值则返回该值，如果两个参数都有值则用逗号连接
     */
    public static String implodeSearchParam(String param1, String param2) {
        String result;
        if (BaseUtils.isEmpty(param1) && BaseUtils.isEmpty(param2)) {
            result = null;
        } else if (!BaseUtils.isEmpty(param1) && !BaseUtils.isEmpty(param2)) {
            result = param1 + "," + param2;
        } else {
            result = BaseUtils.isEmpty(param1) ? param2 : param1;
        }
        return result;
    }

    /**
     * 将文件大小从字节单位转换为指定单位的数值
     *
     * @param len  文件大小，以字节为单位
     * @param unit 目标单位，支持B(字节)、K(千字节)、M(兆字节)、G(吉字节)
     * @return 转换后的文件大小数值
     */
    public static double getFileSize(Long len, String unit) {
        double fileSize = 0;
        if ("B".equals(unit.toUpperCase())) {
            fileSize = (double) len;
        } else if ("K".equals(unit.toUpperCase())) {
            fileSize = (double) len / 1024;
        } else if ("M".equals(unit.toUpperCase())) {
            fileSize = (double) len / 1048576;
        } else if ("G".equals(unit.toUpperCase())) {
            fileSize = (double) len / 1073741824;
        }
        return fileSize;
    }

    /**
     * 判断字符串是否为纯数字
     *
     * @param str 待检测的字符串
     * @return 如果字符串只包含数字字符则返回true，否则返回false
     */
    public static boolean isNumeric(String str) {
        Pattern pattern = Pattern.compile("[0-9]*");
        return pattern.matcher(str).matches();
    }


    /**
     * 将时间戳转换为简短的相对时间描述
     *
     * @param dateline 时间戳（秒）
     * @return 相对时间描述字符串，如"2小时前"、"3天前"等，如果转换失败则返回null
     */
    public static String getShortTime(Integer dateline) {
        String shortstring = null;
        String time = timeStamp2Date(dateline);
        Date date = getDateByString(time);
        if (date == null) return shortstring;

        long now = Calendar.getInstance().getTimeInMillis();
        long deltime = (now - date.getTime()) / 1000;
        if (deltime > 365 * 24 * 60 * 60) {
            shortstring = (int) (deltime / (365 * 24 * 60 * 60)) + "年前";
        } else if (deltime > 24 * 60 * 60) {
            shortstring = (int) (deltime / (24 * 60 * 60)) + "天前";
        } else if (deltime > 60 * 60) {
            shortstring = (int) (deltime / (60 * 60)) + "小时前";
        } else if (deltime > 60) {
            shortstring = (int) (deltime / (60)) + "分前";
        } else if (deltime > 1) {
            shortstring = deltime + "秒前";
        } else {
            shortstring = "1秒前";
        }
        return shortstring;
    }

    /**
     * 将字符串转换为日期对象
     *
     * @param time 日期时间字符串，格式应为"yyyy-MM-dd HH:mm:ss"
     * @return 转换后的Date对象，如果转换失败或输入为null则返回null
     */
    public static Date getDateByString(String time) {
        Date date = null;
        if (time == null)
            return date;

        String date_format = "yyyy-MM-dd HH:mm:ss";
        SimpleDateFormat format = new SimpleDateFormat(date_format);
        try {
            date = format.parse(time);
        } catch (ParseException e) {
            e.printStackTrace();

        }
        return date;
    }

    /**
     * 获取字符串,为空判断
     *
     * @param s 字符串
     * @return 字符串，如果为null则返回空字符串""
     */
    public static String str(String s) {
        return s == null ? "" : s;
    }

    /**
     * 获取单元格的值并转换为字符串格式
     *
     * @param cell Excel单元格对象
     * @return 单元格的字符串表示，如果单元格为空则返回空字符串
     */
    public static String getCellValue(Cell cell) {
        if (cell == null) return "";
        switch (cell.getCellType()) {
            case STRING:
                return cell.getStringCellValue().trim();
            case NUMERIC:  // 数字 or 日期
                double v = cell.getNumericCellValue();
                return v == (long) v ? String.valueOf((long) v) : String.valueOf(v);
            case BOOLEAN:
                return String.valueOf(cell.getBooleanCellValue());
            case FORMULA:
                return cell.getCellFormula();
            default:
                return "";
        }
    }
}
